
/**
** \file       shell_cmd.c
**
** \brief      this function parse the shell_command rule
**
** \author     Ben M'rad Hanna, Laterem Hamza, Boillot Ulysse,
**              De Olivera Guillaume and Nguyen Viet Dung
**
** \version    0.8
**
** \date       26 Novembre 2010
**
*/

#include "rules.h"

static s_sh_cmd              *my_free(int                            n,
                                      s_sh_cmd                       *sh_cmd)
{
  if (n != 1)
  {
    free(sh_cmd->ruleif);
    sh_cmd->ruleif = NULL;
  }

  if (n != 2)
  {
    free(sh_cmd->rulefor);
    sh_cmd->rulefor = NULL;
  }

  if (n != 3)
  {
    free(sh_cmd->rulewhile);
    sh_cmd->rulewhile = NULL;
  }

  if (n != 4)
  {
    free(sh_cmd->rulecase);
    sh_cmd->rulecase = NULL;
  }

  if (n != 5)
  {
    free(sh_cmd->ruleuntil);
    sh_cmd->ruleuntil = NULL;
  }

  return (sh_cmd);
}

static s_sh_cmd         *rule_shell_command1(s_sh_cmd           *sh_cmd)
{
  g_data->lexer = g_data->lexer->next;

  if (g_data->lexer == NULL)
    return (NULL);

  sh_cmd->cmpdlist = calloc(1, sizeof (s_cmpdlist));

  if (rule_compound_list(sh_cmd->cmpdlist) == NULL)
  {
    free(sh_cmd->cmpdlist);
    sh_cmd->cmpdlist = NULL;
    return (NULL);
  }
  if (strcmp(g_data->lexer->token->id, "}") != 0)
  {
    free(sh_cmd->cmpdlist);
    sh_cmd->cmpdlist = NULL;
    return (NULL);
  }

  g_data->lexer = g_data->lexer->next;
  return (sh_cmd);
}

static s_sh_cmd         *rule_shell_command2(s_sh_cmd           *sh_cmd)
{
  g_data->lexer = g_data->lexer->next;

  if (g_data->lexer == NULL)
    return (NULL);

  sh_cmd->cmpdlist = calloc(1, sizeof (s_cmpdlist));

  if (rule_compound_list(sh_cmd->cmpdlist) == NULL)
  {
    free(sh_cmd->cmpdlist);
    sh_cmd->cmpdlist = NULL;
    return (NULL);
  }

  if (strcmp(g_data->lexer->token->id, ")") != 0)
  {
    free(sh_cmd->cmpdlist);
    sh_cmd->cmpdlist = NULL;
    return (NULL);
  }

  g_data->lexer = g_data->lexer->next;
  return (sh_cmd);
}

static s_sh_cmd           *rule_shell_command3(s_sh_cmd         *sh_cmd)
{
  sh_cmd->rulefor = calloc(1, sizeof (s_rulefor));
  sh_cmd->ruleif = calloc(1, sizeof (s_ruleif));
  sh_cmd->ruleuntil = calloc(1, sizeof (s_ruleuntil));
  sh_cmd->rulecase = calloc(1, sizeof (s_rulecase));
  sh_cmd->rulewhile = calloc(1, sizeof (s_rulewhile));

  if (rule_if(sh_cmd->ruleif) != NULL)
    sh_cmd = my_free(1, sh_cmd);

  if (rule_for(sh_cmd->rulefor) != NULL)
    sh_cmd = my_free(2, sh_cmd);

  if (rule_while(sh_cmd->rulewhile) != NULL)
    sh_cmd = my_free(3, sh_cmd);

  if (rule_case(sh_cmd->rulecase) != NULL)
    sh_cmd = my_free(4, sh_cmd);

  if (rule_until(sh_cmd->ruleuntil) != NULL)
    sh_cmd = my_free(5, sh_cmd);

  if (sh_cmd->rulefor != NULL && sh_cmd->ruleif != NULL
      && sh_cmd->ruleuntil != NULL && sh_cmd->rulecase != NULL
      && sh_cmd->rulewhile != NULL)
  {
    sh_cmd = my_free(6, sh_cmd);
    return (NULL);
  }

  return (sh_cmd);
}

s_sh_cmd                *rule_shell_command(s_sh_cmd            *sh_cmd)
{
  if (strcmp(g_data->lexer->token->id, "(") == 0)
  {
    if (rule_shell_command2(sh_cmd) == NULL)
      return (NULL);
  }
  else
  {
    if (strcmp(g_data->lexer->token->id, "{") == 0)
    {
      if (rule_shell_command1(sh_cmd) == NULL)
        return (NULL);
    }
    else
    {
      if (rule_shell_command3(sh_cmd) == NULL)
        return (NULL);

      if (g_data->lexer->next != NULL)
        g_data->lexer = g_data->lexer->next;
    }
  }

  return (sh_cmd);
}
